package com.farm.wcp.controller.file;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.farm.core.config.AppConfig;
import com.farm.core.page.ViewMode;
import com.farm.file.FarmFileServiceInter;
import com.farm.file.domain.FileBase;
import com.farm.file.enums.FileModel;
import com.farm.file.exception.FileExNameException;
import com.farm.file.exception.FileSizeException;
import com.farm.file.util.FileCopyProcessCache;
import com.farm.web.WebUtils;


@RequestMapping("/upload")
@Controller
public class FileUploadController extends WebUtils {
	private static final Logger log = Logger.getLogger(FileUploadController.class);

	@Resource
	private FarmFileServiceInter farmFileServiceImpl;

	@RequestMapping(value = "/PubUploadProcess.do")
	@ResponseBody
	public Map<String, Object> PubUploadProcess(String processkey, HttpSession session) {
		ViewMode view = ViewMode.getInstance();
		Integer process = 0;
		try {
			String filekey = session.getId() + processkey;
			process = FileCopyProcessCache.getProcess(filekey);
		} catch (Exception e) {
			view.setError(e.getMessage(), e);
		}
		return view.putAttr("process", process).returnObjMode();
	}

	
	@RequestMapping(value = "/general.do")
	@ResponseBody
	public Map<String, Object> upload(@RequestParam(value = "file", required = false) MultipartFile file,
			String processkey, String type, HttpServletRequest request, HttpSession session) {
		FileBase filebase = null;
		String url = null;
		ViewMode view = ViewMode.getInstance();
		try {
			if(AppConfig.getBoolean("config.sys.demo")) {
				throw new RuntimeException("演示环境禁止上传文件");
			}
			FileModel fileModel = getFileMOdel(type, file.getOriginalFilename());
			String filekey = session.getId() + processkey;
			filebase = farmFileServiceImpl.saveLocalFile(file, fileModel, getCurrentUser(session), filekey);
			url = farmFileServiceImpl.getDownloadUrl(filebase.getId(), fileModel);
			String filename = getUrlEncodeFileName(filebase.getTitle());
			view.putAttr("fileName", filename);
			view.putAttr("id", filebase.getId());
			view.putAttr("url", url);
		} catch (FileSizeException e) {
			view.setError("文件大小错误:" + e.getMessage(), e);
		} catch (FileExNameException e) {
			view.setError("文件类型错误:" + e.getMessage(), e);
		} catch (Exception e) {
			view.setError(e.getMessage(), e);
		}
		return view.returnObjMode();
	}

	
	@RequestMapping(value = "/downloadUrl.do")
	@ResponseBody
	public Map<String, Object> downloadUrl(String url, String filename, String processkey, HttpServletRequest request,
			HttpSession session) {
		FileBase filebase = null;
		ViewMode view = ViewMode.getInstance();
		try {
			filename = URLDecoder.decode(filename, "UTF-8");
			FileModel fileModel = getFileMOdel(null, filename);
			String filekey = session.getId() + processkey;
			filebase = farmFileServiceImpl.saveRemoteUrlFile(url, filename, fileModel, getCurrentUser(session),
					filekey);
			String downloadurl = farmFileServiceImpl.getDownloadUrl(filebase.getId(), fileModel);
			String basefilename = getUrlEncodeFileName(filebase.getTitle());
			view.putAttr("fileName", basefilename);
			view.putAttr("id", filebase.getId());
			view.putAttr("url", downloadurl);
		} catch (FileSizeException e) {
			view.setError("文件大小错误:" + e.getMessage(), e);
		} catch (FileExNameException e) {
			view.setError("文件类型错误:" + e.getMessage(), e);
		} catch (UnsupportedEncodingException e) {
			view.setError(e.getMessage(), e);
		} catch (IOException e) {
			view.setError(e.getMessage(), e);
		} catch (Exception e) {
			view.setError(e.getMessage(), e);
		}
		return view.returnObjMode();
	}

	
	@RequestMapping("/base64img")
	@ResponseBody
	public Map<String, Object> base64up(String base64, String filename, HttpSession session) {
		FileBase filebase = null;
		String url = null;
		ViewMode view = ViewMode.getInstance();
		try {
			if(AppConfig.getBoolean("config.sys.demo")) {
				throw new RuntimeException("演示环境禁止上传文件");
			}
			base64 = base64.trim();
			if (base64.indexOf(",") > 0) {
				// data:image/png;base64,
				if (base64.indexOf("data:image/") == 0) {
					filename = filename.substring(0, filename.indexOf(".")) + "."
							+ base64.substring(base64.indexOf("/") + 1, base64.indexOf(";"));
				}
				base64 = base64.substring(base64.indexOf(",") + 1);
			}
			FileModel fileModel = getFileMOdel(null, filename);
			byte[] data = Base64.decodeBase64(base64);
			filebase = farmFileServiceImpl.saveLocalFile(data, fileModel, filename, getCurrentUser(session));
			url = farmFileServiceImpl.getDownloadUrl(filebase.getId(), fileModel);
			filename = getUrlEncodeFileName(filebase.getTitle());
			view.putAttr("fileName", filename);
			view.putAttr("id", filebase.getId());
			view.putAttr("url", url);
		} catch (FileSizeException e) {
			view.setError("文件大小错误:" + e.getMessage(), e);
		} catch (FileExNameException e) {
			view.setError("文件类型错误:" + e.getMessage(), e);
		} catch (Exception e) {
			view.setError(e.getMessage(), e);
		}
		return view.returnObjMode();
	}

	// ---------------------------------------------------------------------------------------
	
	private String getUrlEncodeFileName(String fileName) throws UnsupportedEncodingException {
		try {
			return URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20");
		} catch (Exception e) {
			return URLEncoder.encode(fileName, "utf-8");
		}
	}

	
	private FileModel getFileMOdel(String fileModelName, String fileName) throws FileExNameException {
		if (StringUtils.isBlank(fileModelName)) {
			return FileModel.getModelByFileExName(farmFileServiceImpl.getExName(fileName));
		} else {
			return FileModel.getModel(fileModelName);
		}
	}

}
